package com.mdp.tpa.pay.wxpay.ctrl;


import com.google.gson.Gson;
import com.mdp.core.entity.Result;
import com.mdp.core.entity.Tips;
import com.mdp.core.err.BizException;
import com.mdp.core.service.SequenceService;
import com.mdp.core.utils.BaseUtils;
import com.mdp.core.utils.RequestUtils;
import com.mdp.tpa.pay.cm.entity.Orders;
import com.mdp.tpa.pay.cm.entity.UniOrder;
import com.mdp.tpa.pay.cm.client.AcPaymentPushService;
import com.mdp.tpa.pay.cm.service.OrdersService;
import com.mdp.tpa.pay.wxpay.config.WxpayConfig;
import com.mdp.tpa.pay.wxpay.enums.WxTradeState;
import com.mdp.tpa.pay.wxpay.service.WxpayNativeService;
import com.mdp.tpa.pay.wxpay.util.HttpUtils;
import com.mdp.tpa.pay.wxpay.util.WechatPay2ValidatorForRequest;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController("tpa.pay.WxpayNativeController")
@RequestMapping(value="/**/pay/wxpay")
@Api(tags = "网站微信支付APIv3")
public class WxpayNativeController {

    @Resource
    private WxpayNativeService wxPayService;

    @Resource
    private WxpayConfig wxpayConfig;

    @Autowired
    private OrdersService ordersService;

    SequenceService sequenceService=new SequenceService();


    @Autowired
    AcPaymentPushService acPaymentPushService;

    private Logger log= LoggerFactory.getLogger(WxpayNativeController.class);

    /**
     * Native下单
     * @param order
     * @return
     * @throws Exception
     */
    @ApiOperation("调用微信统一下单API-native，生成支付二维码")
    @RequestMapping(value="/uniOrder/native",method= RequestMethod.POST)
    public Result nativePay(@RequestBody UniOrder order){
        log.info("发起支付请求 v3");
        User user= LoginUtils.getCurrentUserInfo();
        if(!StringUtils.hasText(order.getOtype())){
            return Result.error("otype-0","订单类型必须上传");
        }
        if(!StringUtils.hasText(order.getId())){
            return Result.error("id-0","订单编号必须上传");
        }
        Orders orders = ordersService.getOrders(order);

        if(orders==null){
            return Result.error("orders-is-not-exists","订单不存在");
        }else if("3".equals(orders.getOrderStatus())||"1".equals(orders.getPayStatus())){
            return Result.error("orders-had-pay","订单已支付");
        }else if(!"0".equals(orders.getPayStatus()) && !"2".equals(orders.getOrderStatus())){
            return Result.error("orders-not-in-pay","订单暂未需要支付");
        }else {
            Tips tips=new Tips("下单成功");
            Map<String,Object> m=new HashMap<>();
            m.put("tips",tips);
            Map<String,Object> data=new HashMap<>();
            try {
                //用户发起支付，向微信服务器发起请求，微信支付返回支付二维码连接和订单号
                orders.setPayId(sequenceService.getTxFlowNo());
                data = wxPayService.nativePay(orders);

                String spbillCreateIp= RequestUtils.getIpAddr(RequestUtils.getRequest());

                //更新订单preId
                Orders ordersUpdate=new Orders(orders.getId());
                ordersUpdate.setOtype(order.getOtype());
                ordersUpdate.setPrepayTime(new Date());
                ordersUpdate.setPayId(orders.getPayId());
                ordersUpdate.setPayType("1");
                String codeUrl= (String) data.get("codeUrl");// weixin://wxpay/bizpayurl?pr=5i7lirVzz
                String prepayId=codeUrl.substring(codeUrl.indexOf("pr=")+3);
                ordersUpdate.setPrepayId(prepayId);
                ordersService.updatePrepayId(ordersUpdate);


                Map<String,Object> pushOrders=BaseUtils.toMap(orders);
                pushOrders.put("action","createOrder");
                pushOrders.put("ip",spbillCreateIp);
                pushOrders.put("payId",ordersUpdate.getPayId());
                pushOrders.put("prepayId",ordersUpdate.getPrepayId());
                pushOrders.put("prepayTime",ordersUpdate.getPrepayTime());
                pushOrders.put("otype",orders.getOtype());
                pushOrders.put("payType",ordersUpdate.getPayType());
                if("5".equals(order.getOtype())){
                    acPaymentPushService.pushRechargeOrders(pushOrders );
                }else{
                    acPaymentPushService.pushPaymentOrders(pushOrders );
                }
                return Result.ok().setData(data);
            }catch (BizException be){
                return Result.error(be);
            }catch (Exception e){
                return Result.error("uni-order-un-success",e.getMessage());
            }
        }
    }


    /**
     * 支付通知
     * 微信支付通过支付通知接口将用户支付成功消息通知给商户
     */
    @ApiOperation("支付通知")
    @RequestMapping(value="/native/notify",method= RequestMethod.POST)
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response){
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();//应答对象
        try {
            //处理通知参数
            String body = HttpUtils.readData(request);
            Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = (String)bodyMap.get("id");
            log.info("支付通知的id ===> {}", requestId);

            //签名的验证
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(wxpayConfig.getVerifier(), requestId, body);
            if(!wechatPay2ValidatorForRequest.validate(request)){
                log.error("通知验签失败");
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }
            log.info("通知验签成功");

            //处理订单
            wxPayService.processOrder(bodyMap);

            //成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        } catch (Exception e) {
            log.error("支付结果通知处理失败",e);
            //失败应答
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }
    }

    @ApiOperation("查询微信支付状态")
    @RequestMapping(value="/uniOrder/checkOrderStatus",method= RequestMethod.GET)
    public Result checkOrderStatus(String orderId,String payId, String otype){
        log.info("查询微信支付状态 v3");
        Tips tips = new Tips(false, "");
        Map<String,Object> m=new HashMap<>();
        m.put("tips",tips);
        Map<String,Object> data=new HashMap<>();
        try {
            //用户发起支付，向微信服务器发起请求，微信支付返回支付二维码连接和订单号
            Orders order = new Orders(orderId);
            order.setOtype(otype);
            order.setPayId(payId);
            String status = wxPayService.checkOrderStatus(order);
            if(WxTradeState.SUCCESS.getType().equals(status)) {
                return Result.ok("pay-success","支付成功");
            }else {
                return Result.error("pay-error","支付失败");
            }

        }catch (BizException be){
            return Result.error(be);
        }catch (Exception e){
            return Result.error("uni-order-un-success",e.getMessage());
        }
    }

}
